<template>
  <div i="data-table">
    <el-table
      v-loading="isLoading"
      element-loading-background="rgba(0, 0, 0, 0.08)"
      element-loading-text="数据获取中，请稍后..."
      element-loading-spinner="el-icon-loading"
      ref="table"
      :empty-text="emptyText"
      :data="tableData"
      :height="height"
      :max-height="maxHeight"
      :border="noBorder"
      :lazy="lazy"
      :size="size"
      :row-key="rowKey"
      :row-style="rowStyle"
      :tree-props="treeProps"
      :load="handleLoad"
      :show-summary="showSummary"
      :header-cell-style="{
        color: '#111',
        backgroundColor: '#eef1f7',
        padding: '3px',
      }"
      style="font-size: 13px"
      :highlight-current-row="highlightCurrentRow"
      @selection-change="handleSelectionChange"
      @current-change="handleCurrentChange"
      @row-click="handleRowClick"
    >
      <el-table-column v-if="showExpand" type="expand">
        <template slot-scope="scope">
          <slot name="expand" :row="scope.row" :index="scope.$index" />
        </template>
      </el-table-column>
      <el-table-column
        v-if="showSelection"
        type="selection"
        :width="60"
        :selectable="selectable"
      >
      </el-table-column>
      <el-table-column
        v-if="showIndex"
        type="index"
        :label="indexLable"
        :width="indexWidth"
      >
        <template slot-scope="scope">
          <div class="row">
            <div v-if="addRow">
              <a
                class="el-icon-circle-plus make"
                @click="minma(scope)"
                v-if="scope.$index == 0"
                style="font-size: 20px"
              >
              </a>
              <a
                class="el-icon-delete make"
                v-else
                @click="minma(scope)"
                style="font-size: 19px; color: red"
              >
              </a>
            </div>
            <div>{{ scope.$index + 1 }}</div>
          </div>
        </template>
      </el-table-column>

      <template v-for="(item, index) in column">
        <el-table-column
          :key="index"
          :prop="item.prop"
          :label="item.label"
          :min-width="item.minWidth || 140"
          :width="item.width"
          :show-overflow-tooltip="
            item.showTip !== undefined ? item.showTip : true
          "
          :sortable="item.isSort"
          :fixed="item.fixed"
          :align="item.align || 'left'"
          v-if="
            column.length &&
            column[index].label !== '操作' &&
            ((typeof column[index].show === 'function' &&
              column[index].show()) ||
              column[index].show === undefined ||
              column[index].show === true) &&
            (!column[index].permission || showPower(column[index].permission))
          "
        >
          <template slot-scope="scope">
            <!-- 插槽 -->
            <template v-if="item.slot">
              <slot
                :name="scope.column.property"
                :row="scope.row"
                :index="scope.$index"
              ></slot>
            </template>
            <!-- 自定义内容 -->
            <div v-else-if="item.customValue">
              {{ item.customValue(scope.row) }}
            </div>
            <!-- 图片 or 头像 -->
            <div
              v-else-if="
                item.template &&
                (item.template.type === 'pic' ||
                  item.template.type === 'avatar')
              "
              :class="[
                item.template.type === 'avatar' ? 'avatarImg' : 'coverImg',
                item.class,
              ]"
              :style="{
                width: item.template.width,
                height: item.template.width,
                cursor: item.template.cursor || 'normal',
              }"
            >
              <el-image
                :src="scope.row[item.prop]"
                :fit="item.template.fit"
                :preview-src-list="
                  item.template.preview && [scope.row[item.prop]]
                "
                @click="$emit('clickAvatar', scope.row)"
              >
                <div slot="error" class="image-slot">
                  <i class="el-icon-picture-outline"></i>
                </div>
              </el-image>
              <p
                style="text-align: center"
                v-if="item.template.nickName"
                @click="$emit('clickAvatar', scope.row)"
              >
                {{ item.template.nickName(scope.row) }}
              </p>
              <!-- <img :src="scope.row[item.prop]" :style="`object-fit: ${item.template.fit}`" /> -->
            </div>
            <template
              v-else-if="item.template && item.template.type === 'icon'"
            >
              <Svgicon :icon="scope.row[item.prop]" />
            </template>
            <!-- tag标签 -->
            <div v-else-if="item.template && item.template.type === 'tag'">
              <el-tag :type="item.template.tagType[scope.row[item.prop]]">{{
                item.map ? item.map[scope.row[item.prop]] : scope.row[item.prop]
              }}</el-tag>
            </div>
            <!-- 状态 -->
            <div v-else-if="item.template && item.template.type === 'status'">
              <span
                class="table-status"
                :class="scope.row[item.prop] === item.flag ? 'success' : 'fail'"
              >
                {{
                  scope.row[item.prop] === item.flag
                    ? item.template.successTxt
                    : item.template.failTxt
                }}
              </span>
            </div>

            <!-- a标签 -->
            <div v-else-if="item.template && item.template.type === 'a'">
              <el-button
                type="text"
                :disabled="
                  item.template.disabled && item.template.disabled(scope.row)
                "
                @click="
                  item.template.callback &&
                    item.template.callback(scope.row, scope.$index)
                "
              >
                {{ scope.row[item.prop] || "请选择" }}</el-button
              >
            </div>
            <!-- 开关 -->
            <div v-else-if="item.template && item.template.type === 'switch'">
              <el-switch
                v-model="scope.row[item.prop]"
                :active-color="item.template.actColor"
                @change="
                  item.template.callback &&
                    item.template.callback(scope.row, scope.$index)
                "
              >
              </el-switch>
            </div>
            <!-- 数字输入框 -->
            <div
              v-else-if="item.template && item.template.type === 'inputNumber'"
              class="column-flex"
            >
              <span v-if="item.template.prefix" class="prefix">{{
                item.template.prefix
              }}</span>
              <el-input-number
                :style="{ width: (item.template.width || 100) + 'px' }"
                v-model="scope.row[item.prop]"
                controls-position="right"
                size="mini"
                :controls="item.template.controls || false"
                :precision="item.template.precision || 0"
                @change="
                  item.template.callback &&
                    item.template.callback(scope.row, scope.$index)
                "
                :min="item.template.min || 0"
                :max="item.template.max || Infinity"
              >
              </el-input-number>
            </div>
            <!-- 输入框 -->
            <div v-else-if="item.template && item.template.type === 'input'">
              <el-input
                v-model="scope.row[item.prop]"
                :placeholder="item.template.placeholder"
                size="small"
                :type="item.template.inputType"
                :disabled="item.disabled ? !showPower(item.disabled) : false"
                @change="
                  item.template.callback &&
                    item.template.callback(scope.row, scope.$index)
                "
              />
            </div>
            <!-- 星级 -->
            <div
              v-else-if="item.template && item.template.type === 'rate'"
              class="rate-box"
            >
              <el-rate v-if="scope.row[item.prop] > 5" :value="5" disabled>
              </el-rate>
              <el-rate v-else v-model="scope.row[item.prop]" disabled>
              </el-rate>
              <span class="plus" v-if="scope.row[item.prop] > 5">+</span>
            </div>
            <!-- 下拉菜单 -->
            <div v-else-if="item.template && item.template.type === 'select'">
              <el-select
                v-model="scope.row[item.prop]"
                size="small"
                class="inline-select"
                :clearable="item.template.clearable"
                :filterable="item.template.filterable"
                :placeholder="item.template.placeholder"
                :disabled="item.disabled ? !showPower(item.disabled) : false"
                @change="
                  (val) =>
                    item.template.callback &&
                    item.template.callback(
                      scope.row,
                      scope.$index,
                      'change',
                      val
                    )
                "
              >
                <el-option
                  v-for="option in item.template.options"
                  :key="option[item.template.valueKey || 'value']"
                  :label="option[item.template.labelKey || 'label']"
                  :value="option[item.template.valueKey || 'value']"
                >
                </el-option>
              </el-select>
            </div>
            <!-- 时间段 -->
            <div
              v-else-if="item.template && item.template.type === 'time'"
              class="time-select"
            >
              <el-time-select
                v-model="scope.row[item.prop][0]"
                :picker-options="{
                  start: item.template.start || '00:00',
                  end: item.template.end || '23:59',
                  step: item.template.step || '00:01',
                }"
                size="small"
                placeholder="开始时间"
              >
              </el-time-select>
              <span class="separator">-</span>
              <el-time-select
                v-model="scope.row[item.prop][1]"
                :picker-options="{
                  start: item.template.start || '00:00',
                  end: item.template.end || '24:00',
                  step: item.template.step || '00:01',
                }"
                size="small"
                placeholder="结束时间"
              >
              </el-time-select>
            </div>
            <!-- 日期 -->
            <div
              v-else-if="item.template && item.template.type === 'date'"
              class="time-select"
            >
              <el-date-picker
                v-model="scope.row[item.prop]"
                type="date"
                size="small"
                :disabled="item.disabled ? item.disabled : false"
                placeholder="选择日期"
                @change="
                  (val) =>
                    item.template.callback &&
                    item.template.callback(
                      scope.row,
                      scope.$index,
                      'change',
                      val
                    )
                "
              ></el-date-picker>
            </div>
            <!-- 常规 -->
            <template v-else-if="item.type === 'Array'">
              {{ item.map(scope.row[item.prop]) }}
            </template>
            <template v-else>
              {{
                item.map
                  ? item.map[scope.row[item.prop]]
                  : util.isBlank(scope.row[item.prop])
                  ? "--"
                  : scope.row[item.prop]
              }}
            </template>
          </template>
        </el-table-column>
      </template>
      <template
        v-if="
          showPower(
            column[column.length - 1] && column[column.length - 1].template
          )
        "
      >
        <el-table-column
          v-if="
            column.length &&
            column[column.length - 1].label === '操作' &&
            column[column.length - 1].show !== false
          "
          :label="column[column.length - 1].label"
          :width="column[column.length - 1].width || 250"
          :fixed="column[column.length - 1].fixed || 'right'"
        >
          <template slot-scope="scope">
            <div class="operation">
              <template
                v-for="(item, index) in column[column.length - 1].template"
              >
                <div
                  v-if="
                    (typeof item.show === 'function' && item.show(scope.row)) ||
                    item.show === undefined ||
                    item.show === true
                  "
                  :key="index"
                  v-permission="item.permission"
                >
                  <!-- 跳转路由 -->
                  <router-link
                    v-if="item.tag === 'router-link'"
                    :to="
                      Object.keys(item.query || {}).reduce(
                        (a, b) => {
                          a.query[b] = scope.row[b] || item.query[b];
                          return a;
                        },
                        {
                          path:
                            typeof item.path === 'function'
                              ? item.path(scope.row, scope.$index)
                              : item.path,
                          query: {},
                        }
                      )
                    "
                    class="link-btn"
                    tag="a"
                  >
                    {{
                      item.map
                        ? item.map[scope.row[item.prop]]
                        : item.customValue
                        ? item.customValue(scope.row)
                        : item.text
                    }}
                  </router-link>
                  <!-- 普通按钮 -->
                  <template v-if="!item.confirm">
                    <a
                      v-if="item.tag === 'a'"
                      href="javascript:;"
                      class="link-btn"
                      @click.stop="
                        item.callback && item.callback(scope.row, scope.$index)
                      "
                    >
                      {{
                        item.map
                          ? item.map[scope.row[item.prop]]
                          : item.text
                          ? item.text
                          : scope.row[item.prop] === item.flag
                          ? item.actText
                          : item.inactText
                      }}
                    </a>
                    <el-button
                      v-else-if="item.tag === 'button'"
                      class="link-btn"
                      size="mini"
                      :type="
                        (item.type
                          ? item.type
                          : scope.row[item.prop] === item.flag
                          ? item.actType
                          : item.inactType) || ''
                      "
                      @click.stop="
                        item.callback && item.callback(scope.row, scope.$index)
                      "
                    >
                      {{
                        item.map
                          ? item.map[scope.row[item.prop]]
                          : item.text
                          ? item.text
                          : scope.row[item.prop] === item.flag
                          ? item.actText
                          : item.inactText
                      }}
                    </el-button>
                    <a
                      v-else-if="item.tag === 'copy'"
                      href="javascript:;"
                      class="link-btn"
                      v-clipboard="
                        item.copyText
                          ? item.copyText + scope.row[item.prop]
                          : ''
                      "
                      @success="
                        () => {
                          typeof item.handleSuccess === 'function' &&
                            item.handleSuccess();
                        }
                      "
                      @error="
                        () => {
                          typeof item.handleError === 'function' &&
                            item.handleError();
                        }
                      "
                    >
                      {{
                        item.map
                          ? item.map[scope.row[item.prop]]
                          : item.text
                          ? item.text
                          : scope.row[item.prop] === item.flag
                          ? item.actText
                          : item.inactText
                      }}
                    </a>
                  </template>
                  <!-- 带二次确认的按钮 -->
                  <el-popconfirm
                    v-if="item.confirm"
                    :title="item.confirmTxt || '确定执行该操作吗？'"
                    @confirm="item.confirm(scope.row, scope.$index)"
                  >
                    <a
                      v-if="item.tag === 'a'"
                      href="javascript:;"
                      class="link-btn"
                      slot="reference"
                    >
                      {{
                        item.map
                          ? item.map[scope.row[item.prop]]
                          : item.text
                          ? item.text
                          : scope.row[item.prop] === item.flag
                          ? item.actText
                          : item.inactText
                      }}
                    </a>
                    <el-button
                      v-else-if="item.tag === 'button'"
                      class="link-btn"
                      size="mini"
                      :type="
                        (item.type
                          ? item.type
                          : scope.row[item.prop] === item.flag
                          ? item.actType
                          : item.inactType) || ''
                      "
                      slot="reference"
                    >
                      {{
                        item.map
                          ? item.map[scope.row[item.prop]]
                          : item.text
                          ? item.text
                          : scope.row[item.prop] === item.flag
                          ? item.actText
                          : item.inactText
                      }}
                    </el-button>
                  </el-popconfirm>
                </div>
              </template>
            </div>
          </template>
        </el-table-column>
      </template>
    </el-table>
    <slot></slot>

    <div class="talec">
      <el-pagination
        class="pagination"
        v-if="showPage"
        background
        @current-change="changePage"
        :current-page.sync="page"
        :layout="layout"
        :total="total"
        @size-change="sizeChange"
        :page-sizes="[10, 20, 30, 50, 80, 100, 200, 500]"
        :page-size="pageSize"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
import util from "/@/util/util";

export default {
  name: "DataTable",
  props: {
    // 表格数据
    tableData: {
      type: Array,
      default: () => [],
    },
    tableColumn: {
      type: Object,
      default: () => ({}),
    },
    // 是否无边框
    noBorder: {
      type: Boolean,
      default: true,
    },
    // 是否开启展开行功能
    showExpand: {
      type: Boolean,
      default: false,
    },
    // Table 的高度
    height: {
      type: [Number, String],
      default: null,
    },
    // Table 的最大高度
    maxHeight: {
      type: [Number, String],
      default: null,
    },
    // 是否要高亮当前行
    highlightCurrentRow: {
      type: Boolean,
      default: false,
    },
    // 分页组件布局
    layout: {
      type: String,
      default: "total, prev, pager, next, sizes, jumper",
    },
    // 分页总数
    total: {
      type: Number,
      default: 0,
    },
    // 序号是否显示
    showIndex: {
      type: Boolean,
      default: false,
    },
    // 显示行的增加删除
    addRow: {
      type: Boolean,
      default: false,
    },
    // 序号列名
    indexLable: {
      type: String,
      default: "序号",
    },
    // 序号列宽
    indexWidth: {
      type: Number,
      default: 80,
    },
    // 显示分页
    showPage: {
      type: Boolean,
      default: false,
    },
    lazy: {
      type: Boolean,
      default: false,
    },
    size: {
      type: String,
      default: "mini",
    },
    rowKey: {
      type: String,
      default: "id",
    },
    rowStyle: {
      type: [Object, Function],
      default: () => ({}),
    },
    treeProps: {
      type: Object,
      default: () => ({ children: "children", hasChildren: "hasChildren" }),
    },
    // 每页条数
    pageSize: {
      type: Number,
      default: 10,
    },
    // 当前页数
    currentPage: {
      type: Number,
      default: 1,
    },
    // 是否显示多选
    showSelection: {
      type: Boolean,
      default: false,
    },
    // CheckBox 是否可以勾选
    selectable: {
      type: Function,
      default: () => true,
    },
    // 显示合计行
    showSummary: {
      type: Boolean,
      default: false,
    },
    //加载loading
    isLoading: {
      type: Boolean,
      default: false,
    },
    //  无数据是展示
    emptyText: {
      type: String,
      default: "暂无数据",
    },
  },
  data() {
    return {
      page: this.currentPage,
    };
  },
  computed: {
    // 工具类
    util() {
      return util;
    },
    column() {
      return Object.entries(this.tableColumn)
        .map((item) =>
          Object.assign(
            { prop: item[0] },
            typeof item[1] === "string" ? { label: item[1] } : item[1]
          )
        )
        .sort((a, b) => (b.prop === "operation" ? -1 : 0));
    },
  },
  watch: {
    currentPage(newVal) {
      this.page = this.currentPage;
    },
  },
  methods: {
    renderHeader(h, { column }) {
      // h即为cerateElement的简写，具体可看vue官方文档
      alert("msg");
      // return h(
      //   'div',
      //   [
      //     h('span', column.label),
      //     h('i', {
      //       class:'el-icon-location',
      //       style:'color:#409eff;margin-left:5px;'
      //     })
      //   ],
      // );
    },

    // getDateVal(){
    //     console.log(this.$refs.dateRef)
    // },
    // 改变页数后
    changePage(page) {
      this.page = page;
      this.$emit("changePage", page);
    },
    // 每页条数
    sizeChange(size) {
      this.$emit("sizeChange", size);
    },
    // 触发多选框后
    handleSelectionChange(val) {
      this.$emit("changeSelection", val);
    },
    handleCurrentChange(val) {
      this.$emit("changeCurrent", val);
    },
    handleRowClick(row, column, event) {
      this.$emit("rowClick", row, column, event);
    },
    handleLoad(tree, treeNode, resolve) {
      this.$emit("load", tree, treeNode, resolve);
    },
    replaceProp(obj, str, prehook) {
      if (prehook) {
        return prehook(
          obj[str.match(/[a-zA-Z0-9_]+(?=\})/)[0]],
          str.match(/[a-zA-Z0-9_]+(?=\})/)[0],
          obj
        );
      }
      return obj[str.match(/[a-zA-Z0-9_]+(?=\})/)[0]];
    },
    showPower(value = 0) {
      let permissions = JSON.parse(localStorage.getItem("permissions") || "{}");
      if (typeof value === "number") {
        if (value === 0) return false;
        return permissions[value] ? permissions[value].showMenu : false;
      } else {
        let allPass = Array.isArray(value)
          ? value
              .map((item) => item.permission || 0)
              .some((item) => (value > 0 ? permissions[item].showMenu : true))
          : false;
        return allPass;
      }
    },

    minma(e) {
      this.$emit("addRow", e);
    },
  },
};
</script>
<style lang="scss">
[i="data-table"] {
  overflow: hidden;

  .el-table__header {
    thead {
      tr {
        th {
          line-height: 1.3;
          border-right: 1px solid #dbe0e5
        }
      }
    }
  }
  .el-input {
    input {
      width: 100% !important;
    }
  }
  .time-select {
    display: flex;
    .separator {
      margin: 0 20px;
      font-size: 30px;
      line-height: 25px;
      color: #ccc;
    }
  }
  .avatarImg {
    width: 50px;
    // height: 75px;
  }
  .coverImg .el-image {
    width: 100%;
    height: 100%;
  }
  .coverImg {
    width: 160px;
    height: 98px;
  }
  .table-status {
    position: relative;
    left: 0.6rem;
    &.success::before {
      content: "";
      width: 6px;
      height: 6px;
      position: absolute;
      left: -10px;
      top: 50%;
      transform: translateY(-50%);
      border-radius: 50%;
      background: #a3df85;
    }
    &.fail::before {
      content: "";
      width: 6px;
      height: 6px;
      position: absolute;
      left: -10px;
      top: 50%;
      transform: translateY(-50%);
      border-radius: 50%;
      background: red;
    }
  }
  .column-flex {
    display: flex;
    align-items: center;
    .prefix {
      margin-right: 4px;
    }
  }
  .operation {
    display: flex;
    flex-wrap: wrap;
    > div {
      position: relative;
      display: flex;
      align-items: center;
      padding: 5px;
      line-height: 1;
      &::after {
        position: absolute;
        content: "";
        width: 0;
        height: 14px;
        background: #dfe7ec;
        right: 0;
        top: 50%;
        transform: translateY(-50%);
      }
      &:first-child {
        padding-left: 0;
      }
      &:last-child {
        &::after {
          display: none;
        }
      }
    }
  }

  .talec {
    display: flex;
    justify-content: flex-end;
    .pagination {
      margin-top: 30px;
      // position: absolute;
      right: 0px;
    }
  }
}
.row {
  display: flex;
  justify-content: space-between;
  align-items: center;

  .make {
    &:active {
      opacity: 0.5;
    }
  }
}

.el-table .warning-row {
  background: pink !important;
}
</style>
